<!DOCTYPE html>
<html>
<head>
<link rel="help" href="http://www.w3.org/TR/2012/WD-dom-20121206/#interface-characterdata">
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description("Tests that the CharacterData API arguments are correctly validated.");

var text = document.createTextNode("abcd");
shouldBeEqualToString("text.data", "abcd");
shouldBe("text.__proto__.__proto__", "CharacterData.prototype");

// appendData()
shouldNotThrow("text.appendData('efg')");
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.appendData()", '"TypeError: Failed to execute \'appendData\' on \'CharacterData\': 1 argument required, but only 0 present."');
shouldBeEqualToString("text.data", "abcdefg");

// insertData()
text.data = "efg";
shouldNotThrow("text.insertData(0, 'abcd')");
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.insertData()", '"TypeError: Failed to execute \'insertData\' on \'CharacterData\': 2 arguments required, but only 0 present."');
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.insertData(0)", '"TypeError: Failed to execute \'insertData\' on \'CharacterData\': 2 arguments required, but only 1 present."');
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.insertData(999, 'test')", '"IndexSizeError: Failed to execute \'insertData\' on \'CharacterData\': The offset 999 is greater than the node\'s length (7)."');
shouldBeEqualToString("text.data", "abcdefg");
shouldNotThrow("text.insertData(-4294967294, 'test')"); // Wraps to 2, which is a valid offset.
shouldBeEqualToString("text.data", "abtestcdefg");

// deleteData()
text.data = "abcdefg";
shouldNotThrow("text.deleteData(4, 3)");
shouldBeEqualToString("text.data", "abcd");
shouldThrow("text.deleteData()", '"TypeError: Failed to execute \'deleteData\' on \'CharacterData\': 2 arguments required, but only 0 present."');
shouldBeEqualToString("text.data", "abcd");
shouldThrow("text.deleteData(0)", '"TypeError: Failed to execute \'deleteData\' on \'CharacterData\': 2 arguments required, but only 1 present."');
shouldBeEqualToString("text.data", "abcd");
shouldThrow("text.deleteData(999, 3)", '"IndexSizeError: Failed to execute \'deleteData\' on \'CharacterData\': The offset 999 is greater than the node\'s length (4)."');
shouldBeEqualToString("text.data", "abcd");
shouldThrow("text.deleteData(-1, 3)", '"IndexSizeError: Failed to execute \'deleteData\' on \'CharacterData\': The offset 4294967295 is greater than the node\'s length (4)."'); // Wraps to 4294967295 which is greater than the data length
shouldBeEqualToString("text.data", "abcd");
shouldNotThrow("text.deleteData(-4294967294, 2)"); // Wraps to 2, which is a valid offset.
shouldBeEqualToString("text.data", "ab");
shouldNotThrow("text.deleteData(1, 999)"); // Length argument is too large, should be adjusted.
shouldBeEqualToString("text.data", "a");

// ReplaceData()
text.data = "efg";
shouldNotThrow("text.replaceData(0, 0, 'abcd')");
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.replaceData()", '"TypeError: Failed to execute \'replaceData\' on \'CharacterData\': 3 arguments required, but only 0 present."');
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.replaceData(0)", '"TypeError: Failed to execute \'replaceData\' on \'CharacterData\': 3 arguments required, but only 1 present."');
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.replaceData(0, 0)", '"TypeError: Failed to execute \'replaceData\' on \'CharacterData\': 3 arguments required, but only 2 present."');
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.replaceData(999, 3, 'test')", '"IndexSizeError: Failed to execute \'replaceData\' on \'CharacterData\': The offset 999 is greater than the node\'s length (7)."');
shouldBeEqualToString("text.data", "abcdefg");
shouldThrow("text.replaceData(-1, 3, 'test')", '"IndexSizeError: Failed to execute \'replaceData\' on \'CharacterData\': The offset 4294967295 is greater than the node\'s length (7)."'); // Wraps to 4294967295 which is greater than the data length
shouldBeEqualToString("text.data", "abcdefg");
shouldNotThrow("text.replaceData(-4294967294, 0, 'test')"); // Wraps to 2, which is a valid offset.
shouldBeEqualToString("text.data", "abtestcdefg");
shouldNotThrow("text.replaceData(1, 999, 'aaa')"); // Length argument is too large, should be adjusted.
shouldBeEqualToString("text.data", "aaaa");

// substringData()
text.data = "abcdefg";
shouldBeEqualToString("text.substringData(4, 3)", "efg");
shouldThrow("text.substringData()", '"TypeError: Failed to execute \'substringData\' on \'CharacterData\': 2 arguments required, but only 0 present."');
shouldThrow("text.substringData(0)", '"TypeError: Failed to execute \'substringData\' on \'CharacterData\': 2 arguments required, but only 1 present."');
shouldBeEqualToString("text.substringData(4, 999)", "efg"); // Length argument is too large, should be adjusted.
shouldBeEqualToString("text.substringData(4, -1)", "efg"); // Length argument is too large (after wrapping), should be adjusted.
shouldThrow("text.substringData(-1, 2)", '"IndexSizeError: Failed to execute \'substringData\' on \'CharacterData\': The offset 4294967295 is greater than the node\'s length (7)."'); // Wraps to 4294967295 which is greater than the data length
shouldBeEqualToString("text.substringData(-4294967294, 3)", "cde"); // Wraps to 2, which is a valid offset.

</script>
</body>
</html>
